using MediatR;
using RBAC.Domain.Approval;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.Approval;

namespace RBAC.Write.Api.Application.Handler.Approval
{
    /// <summary>
    /// 创建审批流程处理器（可同时创建节点）
    /// </summary>
    public class CreateApprovalProcessHandler : IRequestHandler<CreateApprovalProcessCommand, APIResult<long>>
    {
        private readonly IBaseRepository<ApprovalProcess> approvalProcessRepository;
        private readonly IBaseRepository<ApprovalNode> approvalNodeRepository;
        private readonly ILogger<CreateApprovalProcessHandler> logger;

        public CreateApprovalProcessHandler(
            IBaseRepository<ApprovalProcess> approvalProcessRepository,
            IBaseRepository<ApprovalNode> approvalNodeRepository,
            ILogger<CreateApprovalProcessHandler> logger)
        {
            this.approvalProcessRepository = approvalProcessRepository;
            this.approvalNodeRepository = approvalNodeRepository;
            this.logger = logger;
        }

        /// <summary>
        /// 处理创建命令
        /// </summary>
        public async Task<APIResult<long>> Handle(CreateApprovalProcessCommand request, CancellationToken cancellationToken)
        {
            try
            {
                logger.LogInformation("开始创建审批流程，名称: {ProcessName}", request.ProcessName);

                // 1. 重名校验（排除逻辑删除）
                var duplicate = approvalProcessRepository.GetALL()
                    .FirstOrDefault(x => x.ProcessName == request.ProcessName && !x.IsDeleted);
                if (duplicate != null)
                {
                    return new APIResult<long>
                    {
                        Code = APIEnums.Fail,
                        Msg = "审批流程名称已存在",
                        Data = 0
                    };
                }

                // 2. 组装实体并创建流程
                var process = new ApprovalProcess
                {
                    ProcessName = request.ProcessName,
                    Description = request.Description ?? string.Empty,
                    Status = request.Status,
                    ProcessType = request.ProcessType ?? string.Empty,
                    CreateUser = request.CreateUser ?? "系统"
                };

                var rows = approvalProcessRepository.Create(process);
                if (rows <= 0)
                {
                    logger.LogError("创建审批流程持久化失败：{ProcessName}", request.ProcessName);
                    return new APIResult<long>
                    {
                        Code = APIEnums.Fail,
                        Msg = "创建审批流程失败",
                        Data = 0
                    };
                }

                // 3. 获取新建流程ID（优先使用实体Id，若未回填则兜底查询最大Id）
                long processId = process.Id;
                if (processId <= 0)
                {
                    var latest = approvalProcessRepository.GetALL()
                        .Where(x => !x.IsDeleted && x.ProcessName == request.ProcessName)
                        .OrderByDescending(x => x.Id)
                        .FirstOrDefault();
                    processId = latest?.Id ?? 0;
                }

                if (processId <= 0)
                {
                    logger.LogError("创建审批流程后无法获取ID，名称：{ProcessName}", request.ProcessName);
                    return new APIResult<long>
                    {
                        Code = APIEnums.Fail,
                        Msg = "创建审批流程失败：未获取到流程ID",
                        Data = 0
                    };
                }

                // 4. 批量创建节点（如有）
                // 注意：数据库实际外键列名为 ApprovalProcessId（而非实体中的 ProcessId），
                // 因此这里使用自定义 SQL 显式指定列名，避免因列名不匹配导致的“没有默认值”错误。
                if (request.Nodes != null && request.Nodes.Count > 0)
                {
                    var now = DateTime.Now;
                    const string insertSql = @"INSERT INTO approvalnode 
                        (ApprovalProcessId, ProcessId, NodeName, ApproverId, ApproverName, ApprovalType, NodeOrder, CreateTime, CreateUser, IsDeleted)
                        VALUES (@ApprovalProcessId, @ProcessId, @NodeName, @ApproverId, @ApproverName, @ApprovalType, @NodeOrder, @CreateTime, @CreateUser, 0)";

                    int total = 0;
                    foreach (var n in request.Nodes.OrderBy(x => x.NodeOrder))
                    {
                        long approverId = 0;
                        long.TryParse(n.ApproverId, out approverId);

                        var parameters = new
                        {
                            ApprovalProcessId = processId,
                            ProcessId = processId,
                            NodeName = n.NodeName ?? string.Empty,
                            ApproverId = approverId,
                            ApproverName = n.ApproverName ?? string.Empty,
                            ApprovalType = n.ApprovalType,
                            NodeOrder = n.NodeOrder,
                            CreateTime = now,
                            CreateUser = request.CreateUser ?? "系统"
                        };

                        total += approvalNodeRepository.Execute(insertSql, parameters);
                    }

                    logger.LogInformation("已为流程 {ProcessId} 创建 {Count} 个节点", processId, total);
                }

                // 5. 返回成功与新流程ID
                return new APIResult<long>
                {
                    Code = APIEnums.Success,
                    Msg = "创建审批流程成功",
                    Data = processId
                };
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "创建审批流程发生异常");
                return new APIResult<long>
                {
                    Code = APIEnums.Error,
                    Msg = $"创建审批流程失败：{ex.Message}",
                    Data = 0
                };
            }
        }
    }
}
